﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using MyCommon.DB;
using MyCommon.Helper;
using MyCommon.HttpContextUser;
using MyExtension.Authorizations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace MyExtension.ServiceExtensions
{
    public static class AuthorizationSetup
    {
        public static void AddAuthorizationSetup(this IServiceCollection services) { 
            if(services == null) throw new ArgumentNullException(nameof(services));

            //services.AddAuthorization(options =>
            //{
            //    options.AddPolicy("Client", p => p.RequireRole("Client").Build());
            //    options.AddPolicy("Admin", p => p.RequireRole("Admin").Build());
            //    options.AddPolicy("SystemOrAdmin", p => p.RequireRole("Admin", "System"));
            //    options.AddPolicy("A_S_O", p => p.RequireRole("Admin", "System", "Others"));
            //});


            //读取配置文件
            var symmetricKeyAsBase64 = AppSecretConfig.Audience_Secret_String;
            var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64);
            var signingKey = new SymmetricSecurityKey(keyByteArray);
            var Issuer = Appsettings.app("Audience", "Issuer" );
            var Audience = Appsettings.app(new string[] { "Audience", "Audience" });

            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);

            // 如果要数据库动态绑定，这里先留个空，后边处理器里动态赋值
            var permission = new List<PermissionItem>();

            // 角色与接口的权限要求参数
            var permissionRequirement = new PermissionRequirement(
                "/api/denied",// 拒绝授权的跳转地址（目前无用）
                permission,
                ClaimTypes.Role,//基于角色的授权
                Issuer,//发行人
                Audience,//听众
                signingCredentials,//签名凭据
                expiration: TimeSpan.FromSeconds(60*60 )//接口的过期时间
                );

            // 3、自定义复杂的策略授权
            services.AddAuthorization(options =>
            {
                options.AddPolicy("Permission",
                         policy => policy.Requirements.Add(permissionRequirement));
            });

            // 注入权限处理器
            services.AddScoped<IAuthorizationHandler, PermissionHandler>();
            services.AddSingleton(permissionRequirement);
        }
    }
}
